from rest_framework import serializers

from .models import BookInfo


class PeopleSerializers(serializers.Serializer):
    """
    关联对象查询，
    关联表的序列化器必须定义在主表的前面，否则报找不到的错误
    """
    GENDER_CHOICES = (
        (0, 'male'),
        (1, 'female')
    )
    id = serializers.IntegerField(label='ID', read_only=True)
    name = serializers.CharField(label='名字', max_length=20, )
    gender = serializers.ChoiceField(choices=GENDER_CHOICES, label='性别', required=False)
    description = serializers.CharField(label='描述', max_length=200, allow_null=True, required=False)


def name_valid(value):
    """
    单个字段验证的另一种方法，回调方法的优先级比单独声明验证方法的优先级高
    :param value:
    :return:
    """
    if len(value) < 2:
        raise serializers.ValidationError('书名长度不够')

    return value


# # 模型类序列化器
# class BookSerializers(serializers.ModelSerializer):
#     # 显示指明字段约束
#     peopleinfo_set = PeopleSerializers()
#
#     class Meta:
#         model = BookInfo  # 指明模型类
#         fields = ('id', 'name')  # 指明模型类中的字段
#         read_only_fields = ('id',)
#         extra_kwargs = {  # 为字段添加额外的属性
#             'pub_date': {'required': False},
#             'name': {'max_length': 20, 'validators': [name_valid]}
#         }
#
#     # def create(self, validated_data):
#     #
#     #     return BookInfo.objects.create(**validated_data)
#     #
#     # def update(self, instance, validated_data):
#     #     instance.name = validated_data.get('name', instance.name)
#     #     instance.pub_date = validated_data.get('pub_date', instance.pub_date)
#     #     instance.readcount = validated_data.get('readcount', instance.readcount)
#     #     instance.commentcount = validated_data.get('commentcount', instance.commentcount)
#     #     instance.is_delete = validated_data.get('is_delete', instance.is_delete)
#     #     instance.save()  # 注意要写save方法保存到数据库
#     #
#     #     return instance
#
#     def validate_name(self, value):
#         """
#         对单一字段序列化时，调用ser.is_valid()方法时候进行验证
#         :param value:
#         :return:
#         """
#         if len(value) < 2:
#             raise serializers.ValidationError('书名长度不够')
#
#         # 验证成功就返回
#         return value
#
#     # def validate(self, attrs):
#     #     """
#     #     对多字段进行验证
#     #     :param attrs:
#     #     :return:
#     #     """
#     #     if attrs['readcount'] < attrs['commentcounts']:
#     #         raise serializers.ValidationError('阅读量小于评论量')
#     #
#     #     # 验证通过返回成功字段
#     #     return attrs


class BookSerializers(serializers.Serializer):
    id = serializers.IntegerField(label='ID', read_only=True)  # 这里面的参数都是字段选项验证，validators中的函数是自定义验证
    # name = serializers.CharField(label='名称', required=True, max_length=20, write_only=True)
    name = serializers.CharField(label='名称', required=True, max_length=20, validators=[name_valid])
    pub_date = serializers.DateField(label='出版日期', required=False, allow_null=True)
    readcount = serializers.IntegerField(label='阅读量', required=False, write_only=True)
    commentcount = serializers.IntegerField(label='阅读量', required=False)
    is_delete = serializers.BooleanField(label='是否下架', required=False, default=False)

    # read_only指明该字段只参与序列化操作，write_only指明该字段之进行反序列化操作
    # # serializer.PrimaryKeyRelatedField作用是返回外键的id
    # peopleinfo_set = serializers.PrimaryKeyRelatedField(read_only=True, many=True)
    # # serializer.StringRelatedField返回的是外键模型类__str__返回的名字
    # peopleinfo_set = serializers.StringRelatedField(many=True, read_only=True)
    peopleinfo_set = PeopleSerializers(read_only=True, many=True)

    def create(self, validated_data):

        return BookInfo.objects.create(**validated_data)

    def update(self, instance, validated_data):
        instance.name = validated_data.get('name', instance.name)
        instance.pub_date = validated_data.get('pub_date', instance.pub_date)
        instance.readcount = validated_data.get('readcount', instance.readcount)
        instance.commentcount = validated_data.get('commentcount', instance.commentcount)
        instance.is_delete = validated_data.get('is_delete', instance.is_delete)
        instance.save()  # 注意要写save方法保存到数据库

        return instance

    def validate_name(self, value):
        """
        对单一字段序列化时，调用ser.is_valid()方法时候进行验证
        :param value:
        :return:
        """
        if len(value) < 2:
            raise serializers.ValidationError('书名长度不够')

        # 验证成功就返回
        return value

    # def validate(self, attrs):
    #     """
    #     对多字段进行验证
    #     :param attrs:
    #     :return:
    #     """
    #     if attrs['readcount'] < attrs['commentcounts']:
    #         raise serializers.ValidationError('阅读量小于评论量')
    #
    #     # 验证通过返回成功字段
    #     return attrs
